package com.tristia.resources.impl;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.annotation.Resource;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.sun.jersey.api.NotFoundException;
import com.tristia.dao.GenericDao;
import com.tristia.entity.Review;
import com.tristia.entity.Reviews;
import com.tristia.entity.util.ItemInfoIdComparator;

@Component
@Path("/reviews")
@Scope("request")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML })
public class ReviewsResWs {
	@Resource
	GenericDao<Review, Long> reviewDao;
	@Context 
	UriInfo ui;
	@Context
	Request request;
	private Logger log = Logger.getLogger(this.getClass());
	
	@GET
	public Reviews getReviews() {
		log.info("getReviews entered");
		Reviews reviews = new Reviews();
		Set<Review> reviewTree = new TreeSet<Review>(new ItemInfoIdComparator("ACS"));
		reviewTree.addAll(reviewDao.getAll());
//		List reviewsList = new ArrayList(reviewTree);
//		reviews.setReviews(reviewsList);
		reviews.setReviews(reviewTree);
		log.info("Sending: \n\n" + reviews.toString() + "\n\n");
		return reviews;
	}
	
	@GET
	@Path("/{reviewId}")
	public Review getReview(@PathParam("reviewId") long reviewId) {
		log.info("getReview entered");
		Review review = reviewDao.get(reviewId);
		if (review == null)throw new NotFoundException("Review not found");
		log.info("Sending: \n\n" + review.toString() + "\n\n");
		return review;
	}
	
	@PUT
	public Response updateReview(@QueryParam("id") String id,
			@QueryParam("title") String title) {
		log.info("updateReview entered");
		log.info("title: " + title);
		log.info("id : " + id);
		
		Response r;
//		URI uri =  ui.getAbsolutePath();
		if (StringUtils.hasText(id)) {
			log.info("It has an ID");
			long idd = Long.parseLong(id);
			boolean reviewExists = reviewDao.exists(idd);
			if (reviewExists == true) {
				log.info("We found the review with that id");
				Review review = reviewDao.get(idd);
				review.setTitle(title);
				reviewDao.save(review);
				log.info("Updated successfully");
//				r = Response.created(uri).build();
				r = Response.ok(review).build();
			} else {
				log.info("We do not found the review with that id");
				r = Response.noContent().build();
			}
		} else {
			log.info("It doesn't have an ID");
			log.info("Put the new review");
			Review review = new Review();
			review.setTitle(title);
			reviewDao.save(review);
			log.info("Updated successfully");
			r = Response.ok(review).build();
		}
		return r;
	}
	
	@POST
	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_XML })
	public Response addReview(@QueryParam("title") String title) {
		log.info("addReview entered");
		log.info("title: " + title);

//		SuccessInfo successInfo = new SuccessInfo();
		Response r;
		Review review = new Review();
		review.setTitle(title);
		reviewDao.save(review);
		log.info("Updated successfully");
		r = Response.ok(review).build();
//		successInfo.getSuccesses().add("Created successfully");
		return r;
	}
	
	@DELETE
	@Path("/{reviewId}")
	public void deleteReview(@PathParam("reviewId") String reviewId) {
		if(reviewId!=null) {
			deleteReviewById(reviewId);
		}
		
		MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
		List<String> ids = queryParams.get("reviewId");
		if(ids == null) {
			log.info("\n\nThe ids is null");
		} else {
			for (String currentid : ids) {
				deleteReviewById(currentid);
			}
		}
	}

	private void deleteReviewById(String id) {
		log.info("Delete Id: " + id);
		Review review = reviewDao.get(Long.parseLong(id));
		if (review == null) {
			log.info("Null was returned for ID: " + id);
		} else {
			reviewDao.remove(Long.parseLong(id));
			log.info("Deleted the CD with ID:" + id);
		}
	}

}
